package concurrentsandbox;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaTray;

public class PrintServiceFuture {
	
	public static class PrinterInfoDto {
		public String printerName;
		public List<String> faecher;

		public PrinterInfoDto() {
			this(null, new ArrayList<String>());
		}

		public PrinterInfoDto(String printerName) {
			this(printerName, new ArrayList<String>());
		}

		public PrinterInfoDto(String printerName, List<String> faecher) {
			super();
			this.printerName = printerName;
			this.faecher = faecher;
		}

		@Override
		public String toString() {
			StringBuilder builder = new StringBuilder();
			builder.append(printerName).append("\n");
			for (String fach : faecher) {
				builder.append("- ").append(fach).append("\n");
			}

			return builder.toString();
		}

	}

	public static Future<List<PrinterInfoDto>> createPrintServiceFuture() {
		Future<List<PrinterInfoDto>> future = Executors.newCachedThreadPool()
				.submit(new Callable<List<PrinterInfoDto>>() {
					public List<PrinterInfoDto> call() throws Exception {
						List<PrinterInfoDto> printers = new ArrayList<PrinterInfoDto>();
						PrintService printServices[] = PrintServiceLookup
								.lookupPrintServices(null, null);
						for (PrintService printService : printServices) {
							String name = printService.getName();
							PrinterInfoDto printerInfoDto = new PrinterInfoDto(
									name);
							printers.add(printerInfoDto);
							try {
								Object attributes = printService
										.getSupportedAttributeValues(
												Media.class,
												DocFlavor.SERVICE_FORMATTED.PAGEABLE,
												null);
								if (attributes != null
										&& attributes.getClass().isArray()) {
									Media[] media = (Media[]) attributes;
									for (int iMedia = 0; iMedia < media.length; iMedia++) {
										if (media[iMedia] instanceof MediaTray) {
											MediaTray tray = (MediaTray) media[iMedia];
											printerInfoDto.faecher.add(tray
													.toString().trim());
										}
									}
								}
							} catch (Exception e) {
								// kann vorkommen, bei komischen
								// Drucker-Installationen
							}
						}
						return printers;
					}
				});
		return future;
	}

}
